package com.yc.testupload.crawler.config;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 网站配置管理器
 * 管理所有网站的配置信息，提供配置的加载、存储和获取功能
 */
public class WebsiteConfigManager {
    private static final Logger logger = LogManager.getLogger(WebsiteConfigManager.class);
    private static WebsiteConfigManager instance;
    private Map<String, WebsiteConfig> websiteConfigs;

    // 私有构造函数，实现单例模式
    private WebsiteConfigManager() {
        websiteConfigs = new HashMap<>();
        initDefaultConfigs();
    }

    // 获取单例实例
    public static synchronized WebsiteConfigManager getInstance() {
        if (instance == null) {
            instance = new WebsiteConfigManager();
        }
        return instance;
    }

    /**
     * 初始化默认配置
     * 从JSON配置文件中加载网站配置信息
     */
    private void initDefaultConfigs() {
        loadConfigsFromJson();
    }

    /**
     * 从JSON配置文件中加载配置
     */
    private void loadConfigsFromJson() {
        try {
            Map<String, WebsiteConfig> configs = WebsiteConfigLoader.loadWebsiteConfigs();
            for (Map.Entry<String, WebsiteConfig> entry : configs.entrySet()) {
                String websiteId = entry.getKey();
                WebsiteConfig config = entry.getValue();
                addWebsiteConfig(websiteId, config);
                logger.info("已加载网站配置: {}, 频道数量: {}", 
                        config.getName(), 
                        config.getChannels().size());
            }
        } catch (Exception e) {
            logger.error("从JSON配置文件加载配置失败，使用备用配置: {}", e.getMessage(), e);
            // 如果从JSON加载失败，使用硬编码的备用配置
            addBackupConfigs();
        }
    }

    /**
     * 添加备用配置
     * 当JSON配置文件加载失败时使用
     */
    private void addBackupConfigs() {
        // 添加牛客网配置作为备用
        Map<String, String> interviewRegexPatterns = new HashMap<>();
        // 牛客网面试题相关正则表达式
        interviewRegexPatterns.put("questionPattern", "<div class=\"niubi-question\".*?>(.*?)</div>");
        interviewRegexPatterns.put("answerPattern", "<div class=\"niubi-answer\".*?>(.*?)</div>");
        interviewRegexPatterns.put("titlePattern", "<title>(.*?)</title>");

        // 创建面试题频道配置
        ChannelConfig interviewChannel = new ChannelConfig(
                "interview", 
                "面试题", 
                31, // 对应文库分类ID：31表示面试题
                interviewRegexPatterns
        );

        Map<String, ChannelConfig> niukeChannels = new HashMap<>();
        niukeChannels.put("interview", interviewChannel);

        // 创建牛客网配置
        WebsiteConfig niukeConfig = new WebsiteConfig(
                "牛客网", 
                "nowcoder.com", 
                "https?://.*nowcoder\\.com/.*", 
                niukeChannels
        );

        addWebsiteConfig("nowcoder", niukeConfig);
        logger.info("已添加备用配置: 牛客网");
    }

    /**
     * 添加网站配置
     */
    public void addWebsiteConfig(String websiteId, WebsiteConfig config) {
        websiteConfigs.put(websiteId, config);
    }

    /**
     * 根据网站ID获取网站配置
     */
    public WebsiteConfig getWebsiteConfig(String websiteId) {
        return websiteConfigs.get(websiteId);
    }

    /**
     * 根据URL获取对应的网站配置
     */
    public WebsiteConfig getWebsiteConfigByUrl(String url) {
        for (WebsiteConfig config : websiteConfigs.values()) {
            if (url.matches(config.getUrlRegex())) {
                return config;
            }
        }
        return null;
    }

    /**
     * 获取所有网站配置的ID集合
     */
    public Set<String> getAllWebsiteIds() {
        return websiteConfigs.keySet();
    }

    /**
     * 获取所有网站配置
     */
    public Map<String, WebsiteConfig> getAllWebsiteConfigs() {
        return new HashMap<>(websiteConfigs);
    }

    /**
     * 根据网站ID和频道ID获取频道配置
     */
    public ChannelConfig getChannelConfig(String websiteId, String channelId) {
        WebsiteConfig websiteConfig = getWebsiteConfig(websiteId);
        if (websiteConfig != null) {
            return websiteConfig.getChannelConfig(channelId);
        }
        return null;
    }
}